package a_Graph_DS;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;

/**
 * 测试发现使用hashSet和treeSet构建的图具有一样的顺序性，这有点不正常；
 * 我觉得是因为g.txt里的边太少了，hash函数对这些值hash的结果还是按大小排列的；而treemap结构看来是按照从小到大的顺序输出的；
 * @author 
 *
 */
public class AdjHashSet_try {
	
	private final int E, V;  //常量只要能在构造函数以及之前 初始化就不会报错；
	private HashSet<Integer>[] adj; //存的是点 也就是编号

	public AdjHashSet_try(String graphFile) {
		
		File g = new File(graphFile);
		
		Scanner sc = null;
		try {   //1.8新特性 try(boolean){}catch(){};
			sc = new Scanner(new FileInputStream(g));
		} catch (FileNotFoundException e) {
			throw new IllegalArgumentException("文件地址有误");  //传统写法应该考虑避免下边代码的继续执行，因为try-catch之间不能有代码；
		}
		
		V = sc.nextInt();
		if(V < 0) throw new IllegalArgumentException("V < 0");
		E = sc.nextInt();
		if(E < 0) throw new IllegalArgumentException("E < 0");
		
		adj = new HashSet[V];
		for (int i = 0; i < adj.length; i++) {
			adj[i] = new HashSet<Integer>();
		}
		
		for (int i = 0; i < E; i++) {
			int a = sc.nextInt();
			validateVertex(a);
			int b = sc.nextInt();
			validateVertex(b);
			
			if(a == b) throw new IllegalArgumentException("存在自环边");
			if(adj[a].contains(b))
				continue;
			
			adj[a].add(b);
			adj[b].add(a);
		}
	}  
	
	public Iterable<Integer> adj(int v){
		validateVertex(v);
		return adj[v];
	}
	
	public boolean hasEdge(int v1, int v2) {
		validateVertex(v1);
		validateVertex(v2);
		return adj[v1].contains(v2);  //加边的时候都是无向边，所以判断一个方向即可；
	}
	
	public int degree(int v) {
		validateVertex(v);
		return adj[v].size();
	}
	
	public int getE() {
		return E;
	}
	
	public int getV() {
		return V;
	}

	private void validateVertex(int v) {
		if (v < 0 || v >= V)
			throw new IllegalArgumentException("vertex " + v + "is not valid");
	}
	 
    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();

        sb.append(String.format("V = %d, E = %d\n", V, E));
        for(int v = 0; v < V; v ++){
            sb.append(String.format("%d : ", v));
            for(int w : adj[v])
                sb.append(String.format("%d ", w));
            sb.append('\n');
        }
        return sb.toString();
    }
    
    public static void main(String[] args) {
    	AdjHashSet_try try1 = new AdjHashSet_try("g.txt");
		System.out.println(try1);
//		System.out.println(new AdjHashSet_try("g2.txt"));
		System.out.println(try1.adj(1));
	}
}
